package edu.ntu.cloudroid.xacml.function;

import java.util.Date;
import java.util.List;

import com.sun.xacml.EvaluationCtx;
import com.sun.xacml.attr.AttributeValue;
import com.sun.xacml.attr.BooleanAttribute;
import com.sun.xacml.attr.TimeAttribute;
import com.sun.xacml.cond.EvaluationResult;
import com.sun.xacml.cond.FunctionBase;
import com.sun.xacml.finder.impl.CurrentEnvModule;

import edu.ntu.cloudroid.xacml.Utilities;
import edu.ntu.cloudroid.xacml.XACMLException;
import edu.ntu.cloudroid.xacml.XACMLStrings;

public class SubjectInTimeBoundsOfResource extends FunctionBase
{
   // the parameter types, in order, and whether or not they're bags
   private static final String params[] = { TimeAttribute.identifier,
         TimeAttribute.identifier };
   private static final boolean bagParams[] = { false, false };

   public SubjectInTimeBoundsOfResource()
   {
      super(XACMLStrings.FN_SubjectInTimeBoundsOfResource, 0, params,
            bagParams, BooleanAttribute.identifier, false);
   }

   @SuppressWarnings("rawtypes")
   @Override
   public EvaluationResult evaluate(List inputs, EvaluationCtx context)
   {
      AttributeValue[] argValues = new AttributeValue[inputs.size()];
      EvaluationResult result = evalArgs(inputs, context, argValues);
      if (result != null)
         return result;

      Date lowerTime = ((TimeAttribute) (argValues[0])).getValue();
      Date upperTime = ((TimeAttribute) (argValues[1])).getValue();

      try {
         TimeAttribute currentTimeAttr = (TimeAttribute) Utilities
               .getEnvironmentAttributeValue(
                     CurrentEnvModule.ENVIRONMENT_CURRENT_TIME,
                     TimeAttribute.identifier, context);
         Date currentTime = currentTimeAttr.getValue();

         boolean evalResult;

         // If lower time and upper time are the same, then allow access
         if (lowerTime.compareTo(upperTime) == 0) {
            evalResult = true;
         } else {
            evalResult = lowerTime.compareTo(currentTime) <= 0
                  && currentTime.compareTo(upperTime) <= 0;
         }        
         return EvaluationResult.getInstance(evalResult);
      } catch (XACMLException e) {
         return makeProcessingError("Error in parsing subject ID");
      }
   }
}
